package com.peycard.vista;

import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.hibernate.validator.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.peycard.common.MobileUserDTO;
import com.peycard.common.ReaderControlDTO;
import com.peycard.common.ReaderDTO;
import com.peycard.service.BaseService;
import com.peycard.util.Constantes;
import com.peycard.util.Utils;

@Controller(Constantes.BEAN_DISPOSITIVOS)
@Scope(Constantes.SCOPE_SESSION)
public class DispositivosControlador extends BaseController implements
		Serializable {

	private static final long serialVersionUID = 1L;
	private static final Logger LOGGER = LoggerFactory
			.getLogger(DispositivosControlador.class);
	private long idReader;
	private long idReaderControl;
	private String encryptionKey;
	private String verifyKey;
	private String messageSecurity;
	private String version;
	private MobileUserDTO mobileUser;
	private String brand;
	private String model;
	private String serialNumber;
	private String isActive;
	private String username;
	private String currentToken = "TOKEN";
	private ReaderDTO currentItem;
	private boolean enabled = true;
	private List<ReaderDTO> listItems;
	private List<SelectItem> brandList;
	private List<SelectItem> modelList;
	@NotEmpty
	private String newEncryptionKey;
	@NotEmpty
	private String newVerifyKey;
	@NotEmpty
	private String newMessageSecurity;
	@NotEmpty
	private String newVersion;
	@NotEmpty
	private String newBrand;
	@NotEmpty
	private String newModel;
	@NotEmpty
	private String newSerialNumber;
	private String newIsActive;
	private String newUsername;

	public DispositivosControlador() {
		init();
		currentToken = super.getTokenInContext();
		username = super.userLogged();
		brandList = new ArrayList<SelectItem>();
		modelList = new ArrayList<SelectItem>();
		selectBrand();
	}

	public List<ReaderControlDTO> readerControlList() {
		List<ReaderControlDTO> dtoList = new ArrayList<ReaderControlDTO>();
		try {
			BaseService readerCtrlService = new BaseService();
			readerCtrlService.setToken(currentToken);
			readerCtrlService.listISOMessage(
					Constantes.ISO003_BRAND_AND_MODEL_LIST,
					Constantes.READER_CONTROL_USERNAME, username,
					Constantes.READER_CONTROL_LIST_KEY);
			List<String> readerControlList = readerCtrlService.getList();
			if (readerControlList != null) {
				for (int i = 0; i < readerControlList.size(); i++) {
					String currentDevice = readerControlList.get(i);
					List<String> dataList = Utils.convertList(currentDevice);
					ReaderControlDTO readerCtrl = new ReaderControlDTO();
					readerCtrl = new ReaderControlDTO();
					readerCtrl.setIdReaderControl(new Long(dataList.get(0)));
					readerCtrl.setBrand(dataList.get(1));
					readerCtrl.setModel(dataList.get(2));
					readerCtrl.setPlatform(dataList.get(3));
					readerCtrl.setIsActive(Integer.valueOf(dataList.get(4)));
					dtoList.add(readerCtrl);
				}
				super.setTokenInContext(readerCtrlService.getToken());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return dtoList;
	}

	public String selectBrand() {
		List<ReaderControlDTO> dto = readerControlList();
		brandList = new ArrayList<SelectItem>();
		if (dto.size() > 0) {
			for (int i = 0; i < dto.size(); i++) {
				String currentBrand = dto.get(i).getBrand();
				SelectItem selectBrand = new SelectItem(currentBrand);
				brandList.add(selectBrand);
			}
		} else {
			super.addWarningMessage("No hay marcas disponibles.");
		}
		return "";
	}

	public void selectionChanged(ValueChangeEvent event) {
		enabled = false;
		modelList.clear();
		LOGGER.info("***Llegando a valueChangeEvent***");
		LOGGER.debug("***Llegando a valueChangeEvent***");
		String oneMenuBrand = (String) event.getNewValue();
		List<ReaderControlDTO> dto = readerControlList();
		if (dto.size() > 0) {
			for (int i = 0; i < dto.size(); i++) {
				String currentBrand = dto.get(i).getBrand();
				if (currentBrand.equals(oneMenuBrand)) {
					String currentModel = dto.get(i).getModel();
					idReaderControl = dto.get(i).getIdReaderControl();
					SelectItem selectBrand = new SelectItem(currentModel);
					modelList.add(selectBrand);
				}
			}
		} else {
			super.addWarningMessage("No hay modelos disponibles.");
		}
	}

	private void init() {
		try {
			BaseService service = new BaseService();
			service.listISOMessage(Constantes.ISO003_READER_LIST,
					Constantes.READER_USERNAME, username,
					Constantes.READER_LIST_KEY);
			List<String> readerList = service.getList();
			if (service.getToken() != null) {
				listItems = new ArrayList<ReaderDTO>();

				for (int i = 0; i < readerList.size(); i++) {
					String currentDevice = readerList.get(i);
					List<String> deviceData = Utils.convertList(currentDevice);
					ReaderDTO dto = new ReaderDTO();
					long id = Long.valueOf(deviceData.get(0));
					dto.setIdReader(id);
					dto.setSerialNumber(deviceData.get(1));
					dto.setVersion(deviceData.get(2));
					dto.setEncryptionKey(deviceData.get(3));
					dto.setIsActive(Integer.valueOf(deviceData.get(4)));
					listItems.add(dto);
				}
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
	}

	public String createReader() {
		if (newVerifyKey.equals(newEncryptionKey)) {
			List<Object> newReader = new ArrayList<Object>();
			newReader.add(idReaderControl);
			newReader.add(newSerialNumber);
			newReader.add(newVersion);
			newReader.add(newMessageSecurity);
			newReader.add(newEncryptionKey);
			newReader.add(newUsername);
			newReader.add(1);
			String string = Utils.buildStringData(newReader);
			createUpdateReaderRequest(Constantes.ISO003_NEW_READER, string);
		} else {
			super.addWarningMessage("Las llaves no coinciden.");
		}

		return "";
	}

	public String updateReader() {
		if (verifyKey.equals(encryptionKey)) {
			List<Object> updateReader = new ArrayList<Object>();
			updateReader.add(serialNumber);
			updateReader.add(version);
			updateReader.add(messageSecurity);
			updateReader.add(encryptionKey);
			updateReader.add(username);
			updateReader.add(isActive);
			String string = Utils.buildStringData(updateReader);
			createUpdateReaderRequest(Constantes.ISO003_UPDATE_READER, string);
		} else {
			super.addWarningMessage("Las llaves no coinciden.");
		}

		return "";
	}

	public String deleteReader() {
		List<Object> deleteDeviceData = new ArrayList<Object>();
		deleteDeviceData.add(idReader);
		deleteDeviceData.add(username);
		String deleteString = Utils.buildStringData(deleteDeviceData);
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			boolean response = service.isoMessageRequest(deleteString,
					Constantes.ISO003_DELETE_READER,
					Constantes.DELETE_CONF_METADATA);
			if (response) {
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return "";
	}

	public void createUpdateReaderRequest(String proccessingCode,
			String dataStructure) {
		String metadata = Constantes.CREATE_UPDATE_READER_METADATA;
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			boolean response = service.isoMessageRequest(proccessingCode,
					metadata, dataStructure);
			if (response) {
				String receivedToken = service.getToken();
				if (!receivedToken.equals(currentToken)) {
					super.setTokenInContext(service.getToken());
				} else {
					super.invalidateSession();
				}
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
	}

	private void initValues(ReaderDTO dto) {
		idReader = dto.getIdReader();
		serialNumber = dto.getSerialNumber();
		version = dto.getVersion();
		messageSecurity = dto.getMessageSecurity();
		encryptionKey = dto.getEncryptionKey();
		isActive = String.valueOf(dto.getIsActive());
	}

	public long getIdReader() {
		return idReader;
	}

	public void setIdReader(long idReader) {
		this.idReader = idReader;
	}

	public String getEncryptionKey() {
		return encryptionKey;
	}

	public void setEncryptionKey(String encryptionKey) {
		this.encryptionKey = encryptionKey;
	}

	public String getMessageSecurity() {
		return messageSecurity;
	}

	public void setMessageSecurity(String messageSecurity) {
		this.messageSecurity = messageSecurity;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public MobileUserDTO getMobileUser() {
		return mobileUser;
	}

	public void setMobileUser(MobileUserDTO mobileUser) {
		this.mobileUser = mobileUser;
	}

	public String getSerialNumber() {
		return serialNumber;
	}

	public void setSerialNumber(String serialNumber) {
		this.serialNumber = serialNumber;
	}

	public String getIsActive() {
		return isActive;
	}

	public void setIsActive(String isActive) {
		this.isActive = isActive;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public ReaderDTO getCurrentItem() {
		return currentItem;
	}

	public void setCurrentItem(ReaderDTO currentItem) {
		initValues(currentItem);
		this.currentItem = currentItem;
	}

	public List<ReaderDTO> getListItems() {
		return listItems;
	}

	public void setListItems(List<ReaderDTO> listItems) {
		this.listItems = listItems;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public String getCurrentToken() {
		return currentToken;
	}

	public void setCurrentToken(String currentToken) {
		this.currentToken = currentToken;
	}

	public List<SelectItem> getBrandList() {
		return brandList;
	}

	public void setBrandList(List<SelectItem> brandList) {
		this.brandList = brandList;
	}

	public List<SelectItem> getModelList() {
		return modelList;
	}

	public void setModelList(List<SelectItem> modelList) {
		this.modelList = modelList;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getModel() {
		return model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public String getNewEncryptionKey() {
		return newEncryptionKey;
	}

	public void setNewEncryptionKey(String newEncryptionKey) {
		this.newEncryptionKey = newEncryptionKey;
	}

	public String getNewMessageSecurity() {
		return newMessageSecurity;
	}

	public void setNewMessageSecurity(String newMessageSecurity) {
		this.newMessageSecurity = newMessageSecurity;
	}

	public String getNewVersion() {
		return newVersion;
	}

	public void setNewVersion(String newVersion) {
		this.newVersion = newVersion;
	}

	public String getNewBrand() {
		return newBrand;
	}

	public void setNewBrand(String newBrand) {
		this.newBrand = newBrand;
	}

	public String getNewModel() {
		return newModel;
	}

	public void setNewModel(String newModel) {
		this.newModel = newModel;
	}

	public String getNewSerialNumber() {
		return newSerialNumber;
	}

	public void setNewSerialNumber(String newSerialNumber) {
		this.newSerialNumber = newSerialNumber;
	}

	public String getNewIsActive() {
		return newIsActive;
	}

	public void setNewIsActive(String newIsActive) {
		this.newIsActive = newIsActive;
	}

	public String getNewUsername() {
		return newUsername;
	}

	public void setNewUsername(String newUsername) {
		this.newUsername = newUsername;
	}

	public String getVerifyKey() {
		return verifyKey;
	}

	public void setVerifyKey(String verifyKey) {
		this.verifyKey = verifyKey;
	}

	public String getNewVerifyKey() {
		return newVerifyKey;
	}

	public void setNewVerifyKey(String newVerifyKey) {
		this.newVerifyKey = newVerifyKey;
	}

	public long getIdReaderControl() {
		return idReaderControl;
	}

	public void setIdReaderControl(long idReaderControl) {
		this.idReaderControl = idReaderControl;
	}

}
